package plugin

import (
	"context"
	"fmt"
	"time"

	"github.com/louloulin/dataflare/pkg/message"
)

// ProcessorPlugin 处理器插件接口
type ProcessorPlugin interface {
	Plugin
	// Process 处理消息
	Process(ctx context.Context, msg message.DataMessage) (message.DataMessage, error)
}

// BaseProcessorPlugin 基础处理器插件实现
type BaseProcessorPlugin struct {
	id          string
	version     string
	description string
	config      map[string]interface{}
	enabled     bool
}

// NewBaseProcessorPlugin 创建基础处理器插件
func NewBaseProcessorPlugin(id, version, description string) *BaseProcessorPlugin {
	return &BaseProcessorPlugin{
		id:          id,
		version:     version,
		description: description,
		config:      make(map[string]interface{}),
		enabled:     false,
	}
}

// Initialize 初始化插件
func (p *BaseProcessorPlugin) Initialize(ctx context.Context, config map[string]interface{}) error {
	p.config = config
	return nil
}

// Start 启动插件
func (p *BaseProcessorPlugin) Start(ctx context.Context) error {
	p.enabled = true
	return nil
}

// Stop 停止插件
func (p *BaseProcessorPlugin) Stop(ctx context.Context) error {
	p.enabled = false
	return nil
}

// GetType 获取插件类型
func (p *BaseProcessorPlugin) GetType() PluginType {
	return PluginTypeProcessor
}

// GetID 获取插件ID
func (p *BaseProcessorPlugin) GetID() string {
	return p.id
}

// GetVersion 获取插件版本
func (p *BaseProcessorPlugin) GetVersion() string {
	return p.version
}

// GetDescription 获取插件描述
func (p *BaseProcessorPlugin) GetDescription() string {
	return p.description
}

// GetInfo 返回插件信息
func (p *BaseProcessorPlugin) GetInfo() PluginInfo {
	return PluginInfo{
		ID:          p.id,
		Name:        p.id,
		Type:        PluginTypeProcessor,
		Mode:        PluginModeRPC, // 默认为RPC模式
		Version:     p.version,
		APIVersion:  1,
		Author:      "DataLink",
		Description: p.description,
		License:     "",
		Homepage:    "",
		Config:      p.config,
	}
}

// LoggingProcessorPlugin 日志处理器插件
type LoggingProcessorPlugin struct {
	*BaseProcessorPlugin
	logPrefix string
}

// NewLoggingProcessorPlugin 创建新的日志处理器插件
func NewLoggingProcessorPlugin(id, version, description, logPrefix string) *LoggingProcessorPlugin {
	return &LoggingProcessorPlugin{
		BaseProcessorPlugin: NewBaseProcessorPlugin(id, version, description),
		logPrefix:           logPrefix,
	}
}

// Initialize 初始化插件
func (p *LoggingProcessorPlugin) Initialize(ctx context.Context, config map[string]interface{}) error {
	if err := p.BaseProcessorPlugin.Initialize(ctx, config); err != nil {
		return err
	}

	// 从配置中解析日志前缀
	if prefix, ok := config["log_prefix"].(string); ok {
		p.logPrefix = prefix
	}

	return nil
}

// Process 处理消息
func (p *LoggingProcessorPlugin) Process(ctx context.Context, msg message.DataMessage) (message.DataMessage, error) {
	// 记录消息内容
	fmt.Printf("%s [%s] Processing message: ID=%s, Type=%s, Timestamp=%d\n",
		p.logPrefix,
		time.Now().Format(time.RFC3339),
		msg.GetID(),
		msg.GetType(),
		msg.GetTimestamp(),
	)

	// 返回原始消息，不做修改
	return msg, nil
}

// TransformProcessorPlugin 转换处理器插件
type TransformProcessorPlugin struct {
	*BaseProcessorPlugin
	transformations map[string]string
}

// NewTransformProcessorPlugin 创建新的转换处理器插件
func NewTransformProcessorPlugin(id, version, description string) *TransformProcessorPlugin {
	return &TransformProcessorPlugin{
		BaseProcessorPlugin: NewBaseProcessorPlugin(id, version, description),
		transformations:     make(map[string]string),
	}
}

// Initialize 初始化插件
func (p *TransformProcessorPlugin) Initialize(ctx context.Context, config map[string]interface{}) error {
	if err := p.BaseProcessorPlugin.Initialize(ctx, config); err != nil {
		return err
	}

	// 从配置中解析转换规则
	if transforms, ok := config["transformations"].(map[string]interface{}); ok {
		for k, v := range transforms {
			if strValue, ok := v.(string); ok {
				p.transformations[k] = strValue
			}
		}
	}

	return nil
}

// Process 处理消息
func (p *TransformProcessorPlugin) Process(ctx context.Context, msg message.DataMessage) (message.DataMessage, error) {
	// 克隆消息以避免修改原始消息
	result := msg.Copy()
	data := result.GetData()

	// 应用转换规则
	if mapData, ok := data.(map[string]interface{}); ok {
		for srcField, destField := range p.transformations {
			if value, ok := mapData[srcField]; ok {
				// 添加新字段
				mapData[destField] = value
			}
		}
		result.SetData(mapData)
	}

	return result, nil
}
